package com.wmh.baseservice.user.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wmh.baseservice.admin.pojo.AdProfit;
import com.wmh.baseservice.admin.service.AdProfitService;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.mybatisplus.methods.CommonServiceImpl;
import com.wmh.baseservice.common.utils.CommUtil;
import com.wmh.baseservice.common.wechat.ma.template.WxTemplateMsgUtils;
import com.wmh.baseservice.common.wechat.pay.controller.WxRefundController;
import com.wmh.baseservice.merchant.pojo.MerchantIncomeExpend;
import com.wmh.baseservice.merchant.pojo.MerchantInfo;
import com.wmh.baseservice.merchant.service.MerchantIncomeExpendService;
import com.wmh.baseservice.merchant.service.MerchantInfoService;
import com.wmh.baseservice.system.pojo.SysMessage;
import com.wmh.baseservice.system.pojo.SysParams;
import com.wmh.baseservice.system.service.SysMessageService;
import com.wmh.baseservice.system.service.SysParamsService;
import com.wmh.baseservice.user.mapper.UsAfterSaleApplyMapper;
import com.wmh.baseservice.user.pojo.*;
import com.wmh.baseservice.user.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * @author wmh generator
 * @since 2022-04-27
 */
@Service
public class UsAfterSaleApplyServiceImpl extends CommonServiceImpl<UsAfterSaleApplyMapper, UsAfterSaleApply> implements UsAfterSaleApplyService {

    @Resource
    private UsGoodsOrderService usGoodsOrderService;
    @Resource
    private UsGroupGoodsOrderService usGroupGoodsOrderService;
    @Resource
    private UsInfoService usInfoService;
    @Resource
    private MerchantInfoService merchantInfoService;
    @Resource
    private SysMessageService sysMessageService;
    @Resource
    private UsIncomeExpendService usIncomeExpendService;
    @Resource
    private MerchantIncomeExpendService merchantIncomeExpendService;
    @Resource
    private UsVegetableOrderService usVegetableOrderService;
    @Resource
    private AdProfitService adProfitService;
    @Resource
    private SysParamsService sysParamsService;
    @Resource
    private UsParentOrderService usParentOrderService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(UsAfterSaleApply usAfterSaleApply, UsVegetableOrder usVegetableOrder, UsGroupGoodsOrder usGroupGoodsOrder) {
        if (!save(usAfterSaleApply)) {
            throw new ServiceException(usAfterSaleApply.toString());
        }

        SysMessage sysMessage = new SysMessage().setTitle("您有一条新的售后申请").setContent(String.format("有用户提交了售后申请，订单号:%s", usAfterSaleApply.getOrderNum()));
        if (CommUtil.checkNull(usVegetableOrder)) {
            sysMessage.setMerchantId(usVegetableOrder.getMerchantId());

            //查询是否有父订单
            UsParentOrder parentOrder = usParentOrderService.getOne(new QueryWrapper<UsParentOrder>().like(UsParentOrder.SON_ORDER, usVegetableOrder.getOrderNum()));
            if (CommUtil.checkNull(parentOrder)) {
                //更新所有子订单状态信息
                JSONArray array = JSONArray.parseArray(parentOrder.getSonOrder());
                array.forEach(order -> {
                    UsVegetableOrder sonOrder = usVegetableOrderService.getOne(new QueryWrapper<UsVegetableOrder>()
                            .eq(UsVegetableOrder.ORDER_NUM, order.toString()));
                    sonOrder.setStatus(usVegetableOrder.getStatus());
                    if (CommUtil.checkNull(usVegetableOrder.getAddressId())) {
                        sonOrder.setCourierStatus(usVegetableOrder.getCourierStatus());
                    } else {
                        sonOrder.setTakeTime(usVegetableOrder.getTakeTime());
                    }
                    if (!usVegetableOrderService.updateById(usVegetableOrder)) {
                        throw new ServiceException("发货批量更新订单状态错误");
                    }
                });
            } else {
                if (!usVegetableOrderService.updateById(usVegetableOrder)) {
                    throw new ServiceException(usVegetableOrder.toString());
                }
            }
        } else {
            sysMessage.setMerchantId(usGroupGoodsOrder.getMerchantId());
            if (!usGroupGoodsOrderService.updateById(usGroupGoodsOrder)) {
                throw new ServiceException(usGroupGoodsOrder.toString());
            }
        }
        //发送商家消息
        if (!sysMessageService.save(sysMessage)) {
            throw new ServiceException();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditAfterSale(UsAfterSaleApply usAfterSaleApply) {
        SysParams vegetableCost = sysParamsService.getByIdForUpdate(1L);
        SysParams goodsCost = sysParamsService.getByIdForUpdate(5L);
        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 MM:dd");
        //同意，订单状态修改，售后状态修改，商家余额扣减，然后根据用户支付方式退款,发送模板消息
        if (usAfterSaleApply.getStatus() != -1) {
            //同意，余额退款情况下商家余额要扣除，然后添加用户余额和流水，微信退款的情况下，扣减商家余额，然后添加用户流水，不添加余额
            if (usAfterSaleApply.getType() == 1) {
                //TODO 果蔬商品
                UsVegetableOrder usVegetableOrder = usVegetableOrderService.getOneForUpdate(new QueryWrapper<UsVegetableOrder>().eq(UsGoodsOrder.ORDER_NUM, usAfterSaleApply.getOrderNum()));
                //扣除商家余额：只有在订单金额已经转入商家余额之后才扣除余额
                if (usVegetableOrder.getStatus() >= 2) {
                    //查出订单收支明细，包含主商家和合伙人（如果有的话）
                    List<MerchantIncomeExpend> merchantIncomeExpendList = merchantIncomeExpendService.listForUpdate(new QueryWrapper<MerchantIncomeExpend>()
                            .eq(MerchantIncomeExpend.ORDER_NUM, usAfterSaleApply.getOrderNum()));
                    merchantIncomeExpendList.forEach(income -> {
                        //归还平台手续费(不扣取手续费的收入-扣去手续费后的收入=平台抽成)
                        MerchantInfo merchantInfo = merchantInfoService.getByIdForUpdate(income.getMerchantId());
                        //不扣取手续费的收入（订单总金额*收益占比）
                        BigDecimal notDeductFees = usVegetableOrder.getRealPrice().multiply(BigDecimal.valueOf(merchantInfo.getShares()));
                        //平台抽成手续费（不扣取手续费的收入-已扣取手续费的收入）
                        BigDecimal adServiceCost = notDeductFees.subtract(income.getMoney());
                        //TODO 先归还所有商家的手续费，然后扣除余额
                        AdProfit adProfit = new AdProfit().setOrigin("摘种商品退款手续费归还").setMoney(adServiceCost).setStatus(-1);
                        MerchantIncomeExpend merchantIncomeExpend = new MerchantIncomeExpend()
                                .setOrderNum(usAfterSaleApply.getOrderNum()).setMerchantId(income.getMerchantId())
                                .setStatus(1).setMoney(adServiceCost);
                        merchantInfo.setBalance(merchantInfo.getBalance().add(merchantIncomeExpend.getMoney()));
                        //开始退款，余额不足的情况下扣除保证金，如果保证金加余额都不足，那么清零并记录待支付剩余金额的流水（不冻结商家）
                        if (merchantInfo.getBalance().compareTo(merchantIncomeExpend.getMoney()) < 0) {
                            //商家的余额减去退款的金额
                            BigDecimal balance = merchantInfo.getBalance().subtract(merchantIncomeExpend.getMoney());
                            //剩余的金额+保证金是否足够退款？
                            BigDecimal totalMoney = balance.add(merchantInfo.getMargin());
                            if (totalMoney.compareTo(BigDecimal.ZERO) > 0) {
                                //余额+保证金足够退款，余额扣为0，计算剩余的保证金
                                merchantInfo.setMargin(merchantInfo.getMargin().subtract(merchantIncomeExpend.getMoney().subtract(merchantInfo.getBalance())));
                            } else {
                                //余额和保证金都不够扣除
                                BigDecimal subtract = merchantIncomeExpend.getMoney().subtract(merchantInfo.getBalance().add(merchantInfo.getMargin()));
                                //全扣光，并同时给商家发一条消息并记录待支付的流水，并通知商家补款(如果长时间没补，那么冻结该商家)
                                merchantInfo.setMargin(BigDecimal.ZERO);
                                income.setRemark(String.format
                                        ("果蔬订单号(%s)未完全退款剩余待支付金额:%s", merchantIncomeExpend.getMoney(), subtract));
                                SysMessage merchantSysMessage = new SysMessage().setMerchantId(usVegetableOrder.getMerchantId())
                                        .setTitle("您的保证金已不足，请及时到商家后台缴纳保证金以保证正常使用商家功能")
                                        .setContent(String.format
                                                ("果蔬订单号%s未完全退款，已扣除余额和保证金，剩余待支付金额:%s元，请及时到商家后台缴纳保证金", usAfterSaleApply.getOrderNum(), subtract));
                                if (!sysMessageService.save(merchantSysMessage)) {
                                    throw new ServiceException();
                                }
                            }
                            merchantInfo.setBalance(BigDecimal.ZERO);
                        } else {
                            //扣除余额:商家余额-退款金额
                            merchantInfo.setBalance(merchantInfo.getBalance().subtract(usAfterSaleApply.getRefundAmount()));
                            merchantIncomeExpend.setRemark("果蔬订单余额退款");
                        }
                        //提交事务
                        if (!adProfitService.save(adProfit)) {
                            throw new ServiceException("平台手续费归还失败");
                        }
                        if (!merchantIncomeExpendService.save(merchantIncomeExpend)) {
                            throw new ServiceException("添加商家收入流水失败");
                        }
                        if (!merchantIncomeExpendService.updateById(income)) {
                            throw new ServiceException("修改商家收入流水备注失败");
                        }
                        if (!merchantInfoService.updateById(merchantInfo)) {
                            throw new ServiceException("修改商家余额失败");
                        }
                    });
                }
                //用户收入流水
                UsIncomeExpend usIncomeExpend = new UsIncomeExpend().setType(1).setStatus(1)
                        .setMoney(usAfterSaleApply.getRefundAmount()).setRemark("售后退款").setUsId(usAfterSaleApply.getUsId());
                if (usVegetableOrder.getPayType() == 1) {
                    //余额退款，添加用户余额
                    UsInfo usInfo = usInfoService.getByIdForUpdate(usVegetableOrder.getUsId());
                    usInfo.setBalance(usInfo.getBalance().add(usAfterSaleApply.getRefundAmount()));
                    //提交事务
                    if (!usInfoService.updateById(usInfo)) {
                        throw new ServiceException(usInfo.toString());
                    }
                } else {
                    //微信退款，发起微信退款申请
                    String result = WxRefundController.refundOrder(
                            usVegetableOrder.getOrderNum(), usVegetableOrder.getRealPrice(), usAfterSaleApply.getRefundAmount(), "果蔬订单退款");
                    if (!"ok".equals(result)) {
                        throw new ServiceException(result);
                    }
                    usIncomeExpend.setRemark("售后退款(退至微信零钱)");
                }

                //订单状态修改
                usVegetableOrder.setStatus(-2);
                usVegetableOrder.setAfterSalesStatus(2);


                //用户消息
                SysMessage sysMessage = new SysMessage().setUsId(usAfterSaleApply.getUsId())
                        .setTitle("您的退款申请已通过")
                        .setContent(String.format("款项已转入您的%s中,请注意查收", usVegetableOrder.getPayType() == 1 ? "余额" : "微信零钱"))
                        .setStatus(0);
                if (!usIncomeExpendService.save(usIncomeExpend)) {
                    throw new ServiceException(usIncomeExpend.toString());
                }
                if (!sysMessageService.save(sysMessage)) {
                    throw new ServiceException(sysMessage.toString());
                }
                if (!updateById(usAfterSaleApply)) {
                    throw new ServiceException(usAfterSaleApply.toString());
                }
                if (!usVegetableOrderService.updateById(usVegetableOrder)) {
                    throw new ServiceException(usVegetableOrder.toString());
                }

                UsInfo usInfo = usInfoService.getByIdForUpdate(usAfterSaleApply.getUsId());
                JSONObject object = new JSONObject(true);
                object.put("character_string1", usVegetableOrder.getOrderNum());
                object.put("time2", format.format(usAfterSaleApply.getCreateTime()));
                object.put("thing3", usAfterSaleApply.getRedundReason());
                object.put("thing4", "申请已通过，请进入小程序查看");
                WxTemplateMsgUtils.noticeUserRefund(usInfo.getOpenId(), object);
            }
            if (usAfterSaleApply.getType() == 2) {
                UsGroupGoodsOrder usGoodsOrder = usGroupGoodsOrderService.getOneForUpdate(new QueryWrapper<UsGroupGoodsOrder>().eq(UsGroupGoodsOrder.ORDER_NO, usAfterSaleApply.getOrderNum()));
                if (usAfterSaleApply.getRefundType() == 1) {
                    //用户未收货或未提货的状态下，不扣取商家余额，只返还给用户
                    if (usGoodsOrder.getStatus() >= 4) {
                        //商家支出流水
                        MerchantIncomeExpend merchantIncomeExpend = new MerchantIncomeExpend().setOrderNum(usAfterSaleApply.getOrderNum()).setMerchantId(usGoodsOrder.getMerchantId()).setStatus(-1).setMoney(usAfterSaleApply.getRefundAmount());
                        //余额退款
                        MerchantInfo merchantInfo = merchantInfoService.getByIdForUpdate(usGoodsOrder.getMerchantId());
                        //平台手续费返还
                        if (usGoodsOrder.getFreightPrice() == null) {
                            usGoodsOrder.setFreightPrice(new BigDecimal(0));
                        }
                        BigDecimal cost = usGoodsOrder.getRealPrice().subtract(usGoodsOrder.getFreightPrice()).multiply(new BigDecimal(goodsCost.getValue()));
                        AdProfit adProfit = new AdProfit().setOrigin("团购商品退款手续费归还").setMoney(cost).setStatus(-1);
                        merchantInfo.setBalance(merchantInfo.getBalance().add(cost));
                        MerchantIncomeExpend costIncome = new MerchantIncomeExpend().setOrderNum(usGoodsOrder.getOrderNo()).setRemark("平台手续费归还").setMoney(cost).setStatus(1).setMerchantId(merchantInfo.getId());
                        if (!merchantIncomeExpendService.save(costIncome)) {
                            throw new ServiceException();
                        }
                        if (!adProfitService.save(adProfit)) {
                            throw new ServiceException();
                        }

                        //余额不足的情况下扣除保证金，如果保证金加余额都不足，并记录待支付剩余金额的流水（不冻结商家）
                        if (merchantInfo.getBalance().compareTo(usAfterSaleApply.getRefundAmount()) < 0) {
                            //商家的余额减去退款的金额
                            BigDecimal balance = merchantInfo.getBalance().subtract(usAfterSaleApply.getRefundAmount());
                            //剩余的金额+保证金是否足够退款？
                            BigDecimal totalMoney = balance.add(merchantInfo.getMargin());
                            if (totalMoney.compareTo(BigDecimal.ZERO) > 0) {
                                //余额+保证金足够退款，余额扣为0
                                merchantInfo.setMargin(merchantInfo.getMargin().subtract(usAfterSaleApply.getRefundAmount().subtract(merchantInfo.getBalance())));
                            } else {
                                //余额和保证金都不够扣除
                                BigDecimal subtract = usAfterSaleApply.getRefundAmount().subtract(merchantInfo.getBalance().add(merchantInfo.getMargin()));
                                //全扣光，并同时给商家发一条消息并记录待支付的流水，并通知商家补款(如果长时间没补，那么冻结该商家)
                                merchantInfo.setMargin(BigDecimal.ZERO);
                                merchantIncomeExpend.setRemark(String.format
                                        ("团购订单号(%s)未完全退款剩余待支付金额:%s", usAfterSaleApply.getOrderNum(), subtract));
                                SysMessage merchantSysMessage = new SysMessage().setMerchantId(usGoodsOrder.getMerchantId())
                                        .setTitle("您的保证金已不足，请及时到商家后台缴纳保证金以保证正常使用商家功能")
                                        .setContent(String.format
                                                ("团购订单号%s未完全退款，已扣除余额和保证金，剩余待支付金额:%s元，请及时到商家后台缴纳保证金", usAfterSaleApply.getOrderNum(), subtract));
                                if (!sysMessageService.save(merchantSysMessage)) {
                                    throw new ServiceException();
                                }
                            }
                            merchantInfo.setBalance(BigDecimal.ZERO);
                        } else {
                            //扣除余额:商家余额-退款金额
                            merchantInfo.setBalance(merchantInfo.getBalance().subtract(usAfterSaleApply.getRefundAmount()));
                            merchantIncomeExpend.setRemark("团购订单余额退款");
                        }
                        if (!merchantInfoService.updateById(merchantInfo)) {
                            throw new ServiceException(merchantInfo.toString());
                        }
                        if (!merchantIncomeExpendService.save(merchantIncomeExpend)) {
                            throw new ServiceException(merchantIncomeExpend.toString());
                        }
                    }
                    //用户收入流水
                    UsIncomeExpend usIncomeExpend = new UsIncomeExpend().setType(1).setStatus(1).setMoney(usAfterSaleApply.getRefundAmount()).setRemark("售后退款").setUsId(usAfterSaleApply.getUsId());
                    if (usGoodsOrder.getPayType() == 1) {
                        //用户余额添加
                        UsInfo usInfo = usInfoService.getByIdForUpdate(usGoodsOrder.getUsId());
                        usInfo.setBalance(usInfo.getBalance().add(usAfterSaleApply.getRefundAmount()));
                        if (!usInfoService.updateById(usInfo)) {
                            throw new ServiceException(usInfo.toString());
                        }
                    } else {
                        //微信退款，发起微信退款申请
                        String result = WxRefundController.refundOrder(usGoodsOrder.getOrderNo(), usGoodsOrder.getRealPrice(), usAfterSaleApply.getRefundAmount(), "拼单商品退款");
                        if (!"ok".equals(result)) {
                            throw new ServiceException(result);
                        }
                        usIncomeExpend.setRemark("售后退款(退至微信零钱)");
                    }
                    //用户消息
                    SysMessage sysMessage = new SysMessage().setUsId(usAfterSaleApply.getUsId()).setTitle("您的退款申请已通过").setContent(String.format("款项已转入您的%s中,请注意查收", usGoodsOrder.getPayType() == 1 ? "余额" : "微信零钱")).setStatus(0);
                    //订单状态修改
                    usGoodsOrder.setStatus(-2);
                    usGoodsOrder.setAfterSaleStatus(2);
                    if (!updateById(usAfterSaleApply)) {
                        throw new ServiceException(usAfterSaleApply.toString());
                    }
                    if (!usIncomeExpendService.save(usIncomeExpend)) {
                        throw new ServiceException(usIncomeExpend.toString());
                    }
                    if (!sysMessageService.save(sysMessage)) {
                        throw new ServiceException(sysMessage.toString());
                    }
                    if (!usGroupGoodsOrderService.updateById(usGoodsOrder)) {
                        throw new ServiceException(usGoodsOrder.toString());
                    }
                }
                UsInfo usInfo = usInfoService.getByIdForUpdate(usAfterSaleApply.getUsId());
                JSONObject object = new JSONObject(true);
                object.put("character_string1", usGoodsOrder.getOrderNo());
                object.put("time2", format.format(usAfterSaleApply.getCreateTime()));
                object.put("thing3", usAfterSaleApply.getRedundReason());
                if (usAfterSaleApply.getRefundType() == 2 && usGoodsOrder.getStatus() != 1) {
                    //退货退款情况下通知用户在客户端填写快递单号，发送模板消息
                    SysMessage sysMessage = new SysMessage().setUsId(usAfterSaleApply.getUsId()).setTitle("请填写快递单号").setContent("您的审核单已通过审核，请将货物完整寄出后填写快递单号").setStatus(0);
                    if (!sysMessageService.save(sysMessage)) {
                        throw new ServiceException(sysMessage.toString());
                    }
                    if (!updateById(usAfterSaleApply)) {
                        throw new ServiceException(usAfterSaleApply.toString());
                    }
                    object.put("thing4", "申请已通过，请进入小程序填写快递信息");
                } else {
                    object.put("thing4", "申请已通过，请进入小程序查看");
                }
                WxTemplateMsgUtils.noticeUserRefund(usInfo.getOpenId(), object);
            }
        } else {
            UsInfo usInfo = usInfoService.getByIdForUpdate(usAfterSaleApply.getUsId());
            JSONObject object = new JSONObject(true);
            //拒绝
            if (usAfterSaleApply.getType() == 1) {
                //订单售后状态修改
                UsVegetableOrder usVegetableOrder = usVegetableOrderService.getOneForUpdate(new QueryWrapper<UsVegetableOrder>().eq(UsGoodsOrder.ORDER_NUM, usAfterSaleApply.getOrderNum()));
                usVegetableOrder.setAfterSalesStatus(0);
                if (!usVegetableOrderService.updateById(usVegetableOrder)) {
                    throw new ServiceException(usVegetableOrder.toString());
                }
                object.put("character_string1", usVegetableOrder.getOrderNum());
            }
            if (usAfterSaleApply.getType() == 2) {
                //订单售后状态修改
                UsGroupGoodsOrder usGroupGoodsOrder = usGroupGoodsOrderService.getOneForUpdate(new QueryWrapper<UsGroupGoodsOrder>().eq(UsGroupGoodsOrder.ORDER_NO, usAfterSaleApply.getOrderNum()));
                usGroupGoodsOrder.setAfterSaleStatus(0);
                if (!usGroupGoodsOrderService.updateById(usGroupGoodsOrder)) {
                    throw new ServiceException(usGroupGoodsOrder.toString());
                }
                object.put("character_string1", usGroupGoodsOrder.getOrderNo());
            }
            //售后单修改
            if (!updateById(usAfterSaleApply)) {
                throw new ServiceException(usAfterSaleApply.toString());
            }
            SysMessage sysMessage = new SysMessage().setStatus(0).setUsId(usAfterSaleApply.getUsId()).setTitle("您的退款申请被商家拒绝了，原因是:").setContent(usAfterSaleApply.getRedundReason());
            if (!sysMessageService.save(sysMessage)) {
                throw new ServiceException(sysMessage.toString());
            }
            //发送模板消息提醒用户售后申请被拒绝
            object.put("thing4", "售后申请被拒绝");
            object.put("time2", format.format(usAfterSaleApply.getCreateTime()));
            object.put("thing3", usAfterSaleApply.getRedundReason());
            WxTemplateMsgUtils.noticeUserRefund(usInfo.getOpenId(), object);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmedReturn(UsAfterSaleApply usAfterSaleApply) {
        SysParams goodsCost = sysParamsService.getByIdForUpdate(5L);
        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 MM:dd");
        UsInfo info = new UsInfo();
        if (usAfterSaleApply.getType() == 2) {
            UsGroupGoodsOrder usGoodsOrder = usGroupGoodsOrderService.getOneForUpdate(new QueryWrapper<UsGroupGoodsOrder>().eq(UsGroupGoodsOrder.ORDER_NO, usAfterSaleApply.getOrderNum()));
            if (usGoodsOrder.getStatus() >= 4) {
                //商家支出流水
                MerchantIncomeExpend merchantIncomeExpend = new MerchantIncomeExpend().setOrderNum(usAfterSaleApply.getOrderNum()).setMerchantId(usGoodsOrder.getMerchantId()).setStatus(-1).setMoney(usAfterSaleApply.getRefundAmount());
                //余额退款
                MerchantInfo merchantInfo = merchantInfoService.getByIdForUpdate(usGoodsOrder.getMerchantId());
                //平台手续费返还
                if (usGoodsOrder.getFreightPrice() == null) {
                    usGoodsOrder.setFreightPrice(new BigDecimal(0));
                }
                BigDecimal cost = usGoodsOrder.getRealPrice().subtract(usGoodsOrder.getFreightPrice()).multiply(new BigDecimal(goodsCost.getValue()));
                AdProfit adProfit = new AdProfit().setOrigin("团购商品退款手续费归还").setMoney(cost).setStatus(-1);
                merchantInfo.setBalance(merchantInfo.getBalance().add(cost));
                MerchantIncomeExpend costIncome = new MerchantIncomeExpend().setOrderNum(usGoodsOrder.getOrderNo()).setRemark("平台手续费归还").setMoney(cost).setStatus(1).setMerchantId(merchantInfo.getId());
                if (!merchantIncomeExpendService.save(costIncome)) {
                    throw new ServiceException();
                }
                if (!adProfitService.save(adProfit)) {
                    throw new ServiceException();
                }
                //余额不足的情况下扣除保证金，如果保证金加余额都不足，并记录待支付剩余金额的流水（不冻结商家）
                if (merchantInfo.getBalance().compareTo(usAfterSaleApply.getRefundAmount()) < 0) {
                    //商家的余额减去退款的金额
                    BigDecimal balance = merchantInfo.getBalance().subtract(usAfterSaleApply.getRefundAmount());
                    //剩余的金额+保证金是否足够退款？
                    BigDecimal totalMoney = balance.add(merchantInfo.getMargin());
                    if (totalMoney.compareTo(BigDecimal.ZERO) > 0) {
                        //余额+保证金足够退款，余额扣为0
                        merchantInfo.setMargin(merchantInfo.getMargin().subtract(usAfterSaleApply.getRefundAmount().subtract(merchantInfo.getBalance())));
                    } else {
                        //余额和保证金都不够扣除
                        BigDecimal subtract = usAfterSaleApply.getRefundAmount().subtract(merchantInfo.getBalance().add(merchantInfo.getMargin()));
                        //全扣光，并同时给商家发一条消息并记录待支付的流水，并通知商家补款(如果长时间没补，那么冻结该商家)
                        merchantInfo.setMargin(BigDecimal.ZERO);
                        merchantIncomeExpend.setRemark(String.format
                                ("团购订单号(%s)未完全退款剩余待支付金额:%s", usAfterSaleApply.getOrderNum(), subtract));
                        SysMessage merchantSysMessage = new SysMessage().setMerchantId(usGoodsOrder.getMerchantId())
                                .setTitle("您的保证金已不足，请及时到商家后台缴纳保证金以保证正常使用商家功能")
                                .setContent(String.format
                                        ("团购订单号%s未完全退款，已扣除余额和保证金，剩余待支付金额:%s元，请及时到商家后台缴纳保证金", usAfterSaleApply.getOrderNum(), subtract));
                        if (!sysMessageService.save(merchantSysMessage)) {
                            throw new ServiceException();
                        }
                    }
                    merchantInfo.setBalance(BigDecimal.ZERO);
                } else {
                    //扣除余额:商家余额-退款金额
                    merchantInfo.setBalance(merchantInfo.getBalance().subtract(usAfterSaleApply.getRefundAmount()));
                    merchantIncomeExpend.setRemark("团购订单余额退款");
                }
                if (!merchantInfoService.updateById(merchantInfo)) {
                    throw new ServiceException(merchantInfo.toString());
                }
                if (!merchantIncomeExpendService.save(merchantIncomeExpend)) {
                    throw new ServiceException(merchantIncomeExpend.toString());
                }
            }
            //用户收入流水
            UsIncomeExpend usIncomeExpend = new UsIncomeExpend().setType(1).setStatus(1).setMoney(usAfterSaleApply.getRefundAmount()).setRemark("售后退款").setUsId(usAfterSaleApply.getUsId());
            if (usGoodsOrder.getPayType() == 1) {
                //用户余额添加
                UsInfo usInfo = usInfoService.getByIdForUpdate(usGoodsOrder.getUsId());
                usInfo.setBalance(usInfo.getBalance().add(usAfterSaleApply.getRefundAmount()));
                if (!usInfoService.updateById(usInfo)) {
                    throw new ServiceException(usInfo.toString());
                }
            } else {
                //微信退款，发起微信退款申请
                String result = WxRefundController.refundOrder(usGoodsOrder.getOrderNo(), usGoodsOrder.getRealPrice(), usAfterSaleApply.getRefundAmount(), "拼单商品退款");
                if (!"ok".equals(result)) {
                    throw new ServiceException(result);
                }
                usIncomeExpend.setRemark("售后退款(退至微信零钱)");
            }
            //用户消息
            SysMessage sysMessage = new SysMessage().setUsId(usAfterSaleApply.getUsId()).setTitle("您的退款申请已通过").setContent(String.format("款项已转入您的%s中,请注意查收", usGoodsOrder.getPayType() == 1 ? "余额" : "微信零钱")).setStatus(0);
            //订单状态修改
            usGoodsOrder.setStatus(-2);
            usGoodsOrder.setAfterSaleStatus(2);
            if (!usIncomeExpendService.save(usIncomeExpend)) {
                throw new ServiceException(usIncomeExpend.toString());
            }
            if (!sysMessageService.save(sysMessage)) {
                throw new ServiceException(sysMessage.toString());
            }
            if (!usGroupGoodsOrderService.updateById(usGoodsOrder)) {
                throw new ServiceException(usGoodsOrder.toString());
            }
            if (!updateById(usAfterSaleApply)) {
                throw new ServiceException(usAfterSaleApply.toString());
            }

            JSONObject object = new JSONObject(true);
            object.put("character_string1", usGoodsOrder.getOrderNo());
            object.put("time2", format.format(usAfterSaleApply.getCreateTime()));
            object.put("thing3", usAfterSaleApply.getRedundReason());
            object.put("thing4", "你的订单金额已退回，请进入小程序查看");
            WxTemplateMsgUtils.noticeUserRefund(info.getOpenId(), object);
        }
    }
}
